package org.rest
import grails.converters.JSON
import grails.converters.XML

class CategoriesController {
	
	def list = { 
		def categories = Categories.list()
		response.setHeader("Content-Location",g.createLink(controller:"categories",absolute:"true") as String)
		if (categories.isEmpty()){
			response.status = 204
			render ""
		} else {
			response.status = 200
			withFormat {
				xml  { render(contentType:"text/xml"){
						elements{ 
							categories.each{ c ->
									 category {
										uri(g.createLink(controller:"categories",id:(c.id),absolute:"true"))
										products{ c.products.each { p ->  
													uri(g.createLink(controller:"product",id:(p.id),absolute:"true"))
												}
											}	
									name(c.name)
									picture(c?.picture)	
								}
							}                       
						}   
					}  
				}
				json { render getJSON(categories) }
			}
		}
	}
	
	def show = {
		Categories categories = Categories.get(params.id)
		if (categories) {
			response.status = 200
			response.setHeader("Content-Location",g.createLink(controller:"categories",id:categories.id,absolute:"true") as String)
			withFormat {
				xml  { render (contentType:"text/xml"){
						category {
							products{ categories.products.each { p ->  
									uri(g.createLink(controller:"product",id:(p.id),absolute:"true"))
								}
							}	
							name(categories.name)
							picture(categories?.picture)	
						}
					  }  
					}
				json { render getCategoryJSON(categories) as JSON }
			}
		} else {
			sendNotFoundResponse()
		}
	}	
	
	def create = {
		Categories categories = new Categories(params["categories"])
		if (categories.validate()) {
			categories.save(flush:true);
			response.status = 201
			withFormat {
				xml  { render (contentType:"text/xml"){
						category {
							products{ categories.products.each { p ->  
									uri(g.createLink(controller:"product",id:(p.id),absolute:"true"))
								}
							}	
							name(categories.name)
							picture(categories?.picture)	
						}
					}  
				}
				json { render getCategoryJSON(categories) as JSON }
			}
		} else {
			sendErrorResponse(categories, 403)
		}
	} 	
	
	def delete = {
		Categories categories = Categories.get(params.id)
		if (!categories) {
			sendNotFoundResponse()
		}
		categories.delete();
		response.status = 204
		render ""
	}
	
	def update = {
		Categories categories = Categories.get(params.id)
		if (!categories) {
			sendNotFoundResponse()
		}
		bindData(categories, params["categories"])

		if (categories.validate()) {
			categories.save();
			response.status = 200
			withFormat {
				xml  { render (contentType:"text/xml"){
						category {
							products{ categories.products.each { p ->  
									uri(g.createLink(controller:"product",id:(p.id),absolute:"true"))
								}
							}	
							name(categories.name)
							picture(categories?.picture)	
						}
					}  
				}
				json { render getCategoryJSON(categories) as JSON }
			}
		} else {
			sendErrorResponse(categories, 403)
		}
	} 
	
	def getJSON = { categories ->
		def newList = new ArrayList()
		categories.each { c ->
			newList.add(getCategoryJSON(c))
		}
		def output = [
				categories: newList
				]
		render output as JSON
	}
	
	
	def getCategoryJSON = { c ->
		def categoryMap = new HashMap()
		def productList = new ArrayList()
		categoryMap.put("description", c.description)	
		categoryMap.put("name", c.name)
		categoryMap.put("picture",c.picture)
		
		c.products.each { p -> 
			def productMap = new HashMap()
			productMap.put ("uri", g.createLink(controller:"product", id:p.id,absolute:"true"))
			productList.add(productMap)	
		}
		categoryMap.put("products", productList)
		def uri = g.createLink(controller:"categories", id:c.id,absolute:"true") 
		categoryMap.put("uri",uri)
		return categoryMap
	}
	
	
	private def sendErrorResponse(categories, status) {
		response.status = status
		render contentType: "application/xml", {
			errors {
				categories?.errors?.fieldErrors?.each {err ->
					field(err.field)
					message(g.message(error: err))
				}
			}
		}
	}
	
	
	private def sendNotFoundResponse() {
		response.status = 404
		render contentType: "application/xml", {
			errors {
				message("Categories not found with id: " + params.id)
			}
		}
	}
	
}